package com.esender.search.service.impl;

import com.esender.common.constant.RabbitMQConstants;
import com.esender.common.enums.ExceptionEnums;
import com.esender.common.exception.SearchException;
import com.esender.common.model.StandardReport;
import com.esender.search.service.ElasticsearchService;
import com.esender.search.utils.SearchUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

@Service
@Slf4j
public class ElasticsearchServiceImpl implements ElasticsearchService {
    private static final String CREATED = "created";
    private static final String UPDATED = "updated";
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public void index(String index, String id, String json) throws IOException {
        // 1、构建插入数据的indexRequest
        IndexRequest indexRequest = new IndexRequest();
        // 2、给request设置索引信息，文档id，以及文档内容
        indexRequest.index(index);
        indexRequest.id(id);
        indexRequest.source(json, XContentType.JSON);
        // 3、将request信息发送给es服务

        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        String result = response.getResult().getLowercase();

        if (!CREATED.equals(result)){
            // 添加失败！！
            log.error("【搜索模块-写入数据失败】 index = {},id = {},json = {},result = {}",index,id,json,result);
            throw new SearchException(ExceptionEnums.SEARCH_INDEX_ERROR);
        }
        log.info("【搜索模块-写入数据成功】 索引添加成功index = {},id = {},json = {},result = {}",index,id,json,result);
    }

    @Override
    public boolean exists(String index, String id) throws IOException {
        GetRequest getRequest = new GetRequest(index,id);
        boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
        return exists;
    }

    @Override
    public void update(String index, String id, Map<String, Object> doc) throws IOException {
        // 1、基于exist方法查看当前文档是否存在
        boolean exists = exists(index, id);
        if (!exists){
            // 当前文档不存在
            StandardReport standardReport = SearchUtils.get();
            if (standardReport.getReUpdate()){
                // 第二次已经投递过消息，到这已经是延迟20s了
                log.error("【搜索模块-修改日志】 修改日志失败，report = {}",standardReport);
            }else{
                // 到这开始第二次投递消息
                standardReport.setReUpdate(true);
                rabbitTemplate.convertAndSend(RabbitMQConstants.SMS_GATEWAY_NORMAL_QUEUE,standardReport);
            }
            SearchUtils.remove();
            return;
        }
        // 到这确认文档是存在得可以直接做修改操作
        UpdateRequest updateRequest = new UpdateRequest(index, id);
        updateRequest.doc(doc);
        UpdateResponse response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);

        String result = response.getResult().getLowercase();
        if(!UPDATED.equals(result)){
            // 添加失败！！
            log.error("【搜索模块-修改日志失败】 index = {},id = {},doc = {}",index,id,doc);
            throw new SearchException(ExceptionEnums.SEARCH_UPDATE_ERROR);
        }
        log.info("【搜索模块-修改日志成功】 文档修改成功index = {},id = {},doc = {}",index,id,doc);

    }
}
